package com.titan.demo.common.utils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

public class ProviderUtil {
	// 当前应用配置
	private static final ApplicationConfig application = new ApplicationConfig();
	public static String  nameApplication = "provider.name";
	// 连接注册中心配置
	private static final RegistryConfig registry = new RegistryConfig();
//	public static String  addressRegistry = "zookeeper://192.168.128.100:2181";
	public static String  addressRegistry = "redis://127.0.0.1:6379";

	static  {
		application.setName(nameApplication);
		registry.setAddress(addressRegistry);
	}

	public static Map<String, ProtocolConfig> cacheProtocol = new ConcurrentHashMap<String, ProtocolConfig>();
	private final static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	private static ProtocolConfig get(String nameProtocol, String hostProtocol, Integer portProtocol) {
		String key = CommonUtils.toString(nameProtocol, "://", hostProtocol, ":", portProtocol.toString());
		rwl.readLock().lock();
		try {
			ProtocolConfig protocol = cacheProtocol.get(key);
			if ( protocol==null ) {
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				try {
					protocol = cacheProtocol.get(key);
					if ( protocol==null ) {
				    	// 服务提供者协议配置
				    	protocol = new ProtocolConfig();
				    	protocol.setName(nameProtocol);
				    	protocol.setHost(hostProtocol);
				    	protocol.setPort(portProtocol);
					}
					rwl.readLock().lock();
				} finally {
					rwl.writeLock().unlock();
				}
			}
			return protocol;
		} finally {
			rwl.readLock().unlock();
		}		
	}
	
	
	
	public static void export(String hostProtocol, Integer portProtocol
			, Class<?> interfaceClass, Object referenceService, String versionService
			) throws Exception {
		ProtocolConfig protocol = get("dubbo", hostProtocol, portProtocol);
    	
    	// 服务提供者暴露服务配置
    	ServiceConfig service = new ServiceConfig(); // 此实例很重，封装了与注册中心的连接，请自行缓存，否则可能造成内存和连接泄漏
    	service.setApplication(application);
    	service.setRegistry(registry); // 多个注册中心可以用setRegistries()
    	service.setProtocol(protocol); // 多个协议可以用setProtocols()
    	service.setInterface(interfaceClass);
    	service.setRef(referenceService);
    	service.setVersion(versionService);
//    	service.setRetries(retriesService);
    	
    	// 暴露及注册服务
    	service.export();
	}
}
